import { _decorator, Component, Node, Tween, Label, UITransform, Rect, tween } from 'cc';
import { guideFinger } from '../guide/guideFinger';
import { guideMask } from '../guide/guideMask';
import { GuideForceType, IGuideTips } from '../guide/iGuide';
const { ccclass, property } = _decorator;

@ccclass('forcePanel')
export class forcePanel extends Component {

    @property(guideMask)
    guideMask: guideMask;
    @property(guideFinger)
    guideFinger: guideFinger;
    @property(Label)
    tips: Label;

    private _moveTween: Tween<Node>;

    onEnable() {
        this.activeFinger(false);
        this.activeTips(false);
    }

    onDisable() {
        this.resetMoveTween();
    }

    public activeSelf(isShow: boolean) {
        this.node.active = isShow;
    }

    refresh(context?: any): void {
        this.onRefreshForcePanel(context);
        this.refreshTips(context.tips);
    }

    refreshTips(arg: any) {
        if (arg == null) {
            this.activeTips(false);
            return;
        }

        var tips = arg as IGuideTips;
        this.activeTips(true);
        this.tips.string = tips.getTips();
        this.tips.node.worldPosition = tips.getWorldPos(this.guideFinger.node.worldPosition);
    }

    private activeFinger(isShow: boolean) {
        this.guideFinger.activeFinger(isShow);
    }

    private activeTips(isShow: boolean) {
        this.tips.node.active = isShow;
    }

    private onRefreshForcePanel(context: any) {
        var type = context.type;
        switch (type) {
            case GuideForceType.Click:
                this.doGuideClickShow(context.node);
                break;
            case GuideForceType.Move:
                this.doGuideMoveShow(context.nodes, context.moveTime || 1);
                break;
            default:
                console.error(`未定义当前类型的解析，请检查：${type}`);
                return;
        }
    }

    private doGuideClickShow(node: Node) {
        this.guideFinger.node.worldPosition = node.worldPosition;
        this.guideFinger.activeAnima(true);
        this.activeFinger(true);
        var trans = node.getComponent(UITransform);
        this.guideMask.digRect(new Rect(node.worldPosition.x, node.worldPosition.y, trans.width * this.getScale(node, true), trans.height * this.getScale(node, false)));
    }

    private doGuideMoveShow(nodes: Node[], time: number) {
        var leftNode = nodes[0].worldPosition.x > nodes[1].worldPosition.x ? nodes[1] : nodes[0];
        var rightNode = leftNode == nodes[0] ? nodes[1] : nodes[0];
        var leftTrans = leftNode.getComponent(UITransform);
        var rightTrans = rightNode.getComponent(UITransform);
        var x = leftNode.worldPosition.x - leftTrans.width / 2;
        var width = Math.abs(rightNode.worldPosition.x - leftNode.worldPosition.x) + leftTrans.width / 2 + rightTrans.width / 2;

        var upNode = nodes[0].worldPosition.y > nodes[1].worldPosition.y ? nodes[0] : nodes[1];
        var downNode = upNode == nodes[0] ? nodes[1] : nodes[0];
        var upTrans = upNode.getComponent(UITransform);
        var downTrans = downNode.getComponent(UITransform);
        var y = downNode.worldPosition.y - downTrans.height / 2;
        var height = Math.abs(upNode.worldPosition.y - downNode.worldPosition.y) + upTrans.height / 2 + downTrans.height / 2;

        this.guideMask.digRect(new Rect(x + width / 2, y + height / 2, width, height));

        this.guideFinger.activeAnima(false);
        this.activeFinger(true);
        this.doFingerMove(nodes[0], nodes[1], time);
    }

    private doFingerMove(fromNode: Node, toNode: Node, time: number, isLoop: boolean = true) {
        this.guideFinger.node.worldPosition = fromNode.worldPosition;
        this.resetMoveTween();
        this._moveTween = tween(this.guideFinger.node).to(time, { worldPosition: toNode.worldPosition }).call(() => {
            if (isLoop) {
                this.doFingerMove(fromNode, toNode, time, isLoop);
            } else {
                this.resetMoveTween();
            }
        })
        this._moveTween.start();
    }

    private resetMoveTween() {
        this._moveTween && this._moveTween.stop();
        this._moveTween = null;
    }

    private getScale(node: Node, isX: boolean): number {
        if (!node)
            return 1;

        var scale = isX ? node.scale.x : node.scale.y;
        scale *= this.getScale(node.parent, isX);
        return scale;
    }
}


